﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using Zzva.DomainObject;
using Zzva.Common;
using Zzva.ESB;


namespace Zzva.DomainObjectReg
{
    public abstract class TRegDirBase
    {
        //protected Collection<TDirBase> mvarListDir; 
        protected Collection<TDirBase> mvarFullListDir;
        protected TSortValue mvarSortValue;
        protected Collection<TFilterValue> mvarListFilter;
        protected TDirBase mvarCurItem;
        public event EventHandler EventFindDir;
        public event EventHandler EventUpdateList;




        ////
        //Флаг синхронизации текщего листа с текущим состоянием
        //рассинхронизация происходит при
        //добавлении, изменении, удалениии (именяются итемы)
        //изменению соритровке и фильтрации
        protected bool mvarFlgSinhroCurListAndCurState;
        private Collection<TDirBase> mvarCurListDir;


////        //Возвращает текущее представление справочника с учетом фильта и сортировки
////        protected Collection<TDirBase> GetCurList()
////        {
////            try
////            {
////                Collection<TDirBase> lCurList = new Collection<TDirBase>();
////                IEnumerable<TDirBase> hhh = null;
////
////                //Sort
////                hhh = OrderListBySetSort(hhh);
////
////                //Filter
////                hhh = SelectListBySetFilter(hhh);
////                foreach (TDirBase h in hhh) { lCurList.Add(h); }
////                return lCurList;
////            }
////            catch (Exception e) { throw e; }
////            finally { }
////        }

        //Возвращает текущее представление справочника с учетом фильта и сортировки
        protected Collection<TDirBase> GetCurList()
        {
            try
            {
                if (mvarFlgSinhroCurListAndCurState == false)
                {
                    Collection<TDirBase> lCurList = new Collection<TDirBase>();
                    IEnumerable<TDirBase> hhh = null;

                    //Sort
                    hhh = OrderListBySetSort(hhh);

                    //Filter
                    hhh = SelectListBySetFilter(hhh);
                    foreach (TDirBase h in hhh) { lCurList.Add(h); }

                    mvarCurListDir = lCurList;
                    mvarFlgSinhroCurListAndCurState = true;
                }

                return mvarCurListDir;
            }
            catch (Exception e) { throw e; }
            finally { }
        }





        #region Filter...

        public virtual void FilterDel()
        {
            try
            {
                mvarListFilter.Clear();


                ////
                mvarFlgSinhroCurListAndCurState = false;


                Collection<TDirBase> lCurList;
                lCurList = GetCurList();

                TDirBase lFirstItem;
                lFirstItem = GetFirstItem(lCurList);
                mvarCurItem = lFirstItem;

                //дальше здесь событие что обновлено
                FireEventUpdateList(EventArgs.Empty);

            }
            catch (Exception e1) { throw e1; }
            finally { }
        }

        public virtual void FilterAdd(TFilterValue pFilterValue)
        {
            try
            {

                if (pFilterValue.FilterTemplate.Trim() != "")//Фильтр с пустой строкой игнорируются
                {

                    //Изменяем алиас на код поля
                    TFilterValue lFilterValue;
                    string lFieldObozn;
                    lFieldObozn = GetColumnOboznByAlias(pFilterValue.FieldObozn);
                    if (lFieldObozn == "") { throw (new CommonException("Нет обозначения по алиасу")); }
                    lFilterValue = new TFilterValue(lFieldObozn, pFilterValue.FilterTemplate);


                    mvarListFilter.Add(lFilterValue);

                    ////
                    mvarFlgSinhroCurListAndCurState = false;

                    Collection<TDirBase> lCurList;
                    lCurList = GetCurList();

                    TDirBase lFirstItem;
                    lFirstItem = GetFirstItem(lCurList);
                    mvarCurItem = lFirstItem;

                    //дальше здесь событие что обновлено
                    FireEventUpdateList(EventArgs.Empty);
                }
            }
            catch (Exception e1) { throw e1; }
            finally { }
        }

        #endregion

        public virtual void Sort(TSortValue pSortValue)
        {
            try
            {

                //Изменяем алиас на код поля
                TSortValue lSortValue;
                string lFieldObozn;
                lFieldObozn = GetColumnOboznByAlias(pSortValue.FieldObozn);
                if (lFieldObozn == "") { throw (new CommonException("Нет обозначения по алиасу")); }
                lSortValue = new TSortValue(lFieldObozn, pSortValue.SortType);

                mvarSortValue = lSortValue;


                ////
                mvarFlgSinhroCurListAndCurState = false;


                Collection<TDirBase> lCurList;
                lCurList = GetCurList();

                TDirBase lFirstItem;
                lFirstItem = GetFirstItem(lCurList);
                mvarCurItem = lFirstItem;

                //дальше здесь событие что обновлено
                FireEventUpdateList(EventArgs.Empty);
            }

            catch (Exception e1) { throw e1; }
            finally { }
        }


        #region Constructors....


        protected TRegDirBase(Collection<TDirBase> pFullListDir)
        {
            try
            {
                mvarFullListDir = pFullListDir;


                //!!!!!!!!!!!!!!!!!!!!!!
                //Фильтр по умолчанию вернуть из усстановок а пока так
                mvarListFilter = new Collection<TFilterValue>();


                //!!!!!!!!!!!!!!!!!!!!!!
                //Здесь сорт валуе по умолчанию вернуть надо и з установок а пока так
                mvarSortValue = new TSortValue("Obozn", ESortType.OrderForward);



                ////
                mvarFlgSinhroCurListAndCurState = false;





                //Вызывается список с учетом сртировки и фильтрации по умолчанию
                Collection<TDirBase> lCurList;
                lCurList = GetCurList();

                //И устанавливается текущая запись по умолчанию
                TDirBase lFirstItem;
                lFirstItem = GetFirstItem(lCurList);
                mvarCurItem = lFirstItem;

            }

            catch (Exception e1) { throw e1; }
            finally { }



        }

        #endregion


        #region (Примеры использования делегата public delegate TResult Func<T, TResult>(T arg)) в операциях LINQ
        //1 метод - делегат внешняя функция
        //Func<TDirITCompany, string> lSelector = TestDelegateFuncGetSelector;
        //var hhh = mvarListDir.OrderBy(lSelector);


        //2 метод - делегат внешняя функция
        //Func<TDirITCompany, string> lSelector;
        //lSelector  = TestDelegateFuncGetSelector;
        //var hhh = mvarListDir.OrderBy(lSelector);


        //3 метод с использованием анонимной фукнкции
        //Func<TDirITCompany, string> lSelector;
        //lSelector = delegate(TDirITCompany lDirITCompany)
        //{
        //    return lDirITCompany.Obozn;
        //};
        //
        //var hhh = mvarListDir.OrderBy(lSelector);



        //4 метод с использованием анонимной фукнкции
        //Func<TDirITCompany, string> lSelector = delegate(TDirITCompany lDirITCompany)
        //{
        //    return lDirITCompany.Obozn;
        //};
        //
        //var hhh = mvarListDir.OrderBy(lSelector);


        //5 метод с использованием лямбада выражения в описании функции
        //Func<TDirITCompany, string> lSelector = h => h.Obozn;
        //var hhh = mvarListDir.OrderBy(lSelector);


        //6 метод с использованием лямбада выражения в описании функции
        //Func<TDirITCompany, string> lSelector;
        //lSelector = h => h.Obozn;
        //var hhh = mvarListDir.OrderBy(lSelector);


        //7метод с использованием лямбада выражения в описании функции
        //Func<TDirITCompany, string> lSelector;
        //lSelector = h =>
        //{
        //    string k = h.Obozn; 
        //    return k;
        //};
        //var hhh = mvarListDir.OrderBy(lSelector);

        //8метод с использованием лямбада выражения в описании функции
        //var hhh = mvarListDir.OrderBy(h => h.Obozn);
        #endregion



















































































        public string TitleFull
        {
            get
            {
                try
                {
                    string lTitleFull;
                    string lListFilterToString;

                    lListFilterToString = ListFilterToString;

                    if (lListFilterToString == "") { lTitleFull = Title; }
                    else { lTitleFull = Title + ": " + lListFilterToString; }

                    return lTitleFull;
                }
                catch (Exception e1) { throw e1; }
                finally { }
            }
        }

        protected string ListFilterToString 
        {
            get
            {
                try
                {
                    string lListFilterToString = "";
                    int lIndex = 0;

                    if (mvarListFilter.Count != 0)
                    {
                       foreach (TFilterValue lFilterValue in mvarListFilter)
                       {
                          if (lIndex == 0){lListFilterToString = lFilterValue.FilterTemplate;}
                          else{lListFilterToString = lListFilterToString + " + " + lFilterValue.FilterTemplate;}

                          lIndex = lIndex + 1;
                       }
                    }
                    return lListFilterToString;
                }

                catch (Exception e1) { throw e1; }
                finally { }
            }
       
        }







////        //Ищет в заданном списке элемент справочника в заданном поле по заданному шаблону
////        protected virtual TDirBase FindLastDirInList
////            (string pFieldObozn, string pFieldTemplate, IEnumerable<TDirBase> pList)
////        {
////            try
////            {
////                TDirBase lDirBase;
////                lDirBase = null;
////
////                //готовим делегата условия
////                Func<TDirBase, bool> lPredicate;
////                lPredicate = null;
////                switch (pFieldObozn)
////                {
////                    case "Id":
////                        lPredicate = d => d.Id.ToString().ToLower().Contains(pFieldTemplate.ToLower());
////                        lDirBase = pList.LastOrDefault(lPredicate);
////                        break;
////                    case "Obozn":
////                        lPredicate = d => d.Obozn.ToLower().Contains(pFieldTemplate.ToLower());
////                        lDirBase = pList.LastOrDefault(lPredicate);
////                        break;
////                    case "Naim":
////                        lPredicate = d => d.Naim.ToLower().Contains(pFieldTemplate.ToLower());
////                        lDirBase = pList.LastOrDefault(lPredicate);
////                        break;
////                    default:
////                        break;
////                }
////                return lDirBase;
////            }
////            catch (Exception e1) { throw e1; }
////            finally { }
////        }

        //Ищет в заданном списке элемент справочника в заданном поле по заданному шаблону
        private  TDirBase FindLastDirInList
            (string pFieldObozn, string pFieldTemplate, IEnumerable<TDirBase> pList)
        {
            try
            {
                TDirBase lDirBase = null;

                //готовим делегата условия
                Func<TDirBase, bool> lPredicate = null;

                lPredicate = d => d.GetAttrib(pFieldObozn).ToString().ToLower().Contains(pFieldTemplate.ToLower());    
                lDirBase = pList.LastOrDefault(lPredicate);

                return lDirBase;
            }
            catch (Exception e1) { throw e1; }
            finally { }
        }




////        //Ищет в заданном списке элемент справочника в заданном поле по заданному шаблону
////        protected virtual TDirBase FindFirstDirInList
////            (string pFieldObozn, string pFieldTemplate, IEnumerable<TDirBase> pList)
////        {
////            try
////            {
////                TDirBase lDirBase;
////                lDirBase = null;
////
////                //готовим делегата условия
////                Func<TDirBase, bool> lPredicate;
////                lPredicate = null;
////                switch (pFieldObozn)
////                {
////                    case "Id":
////                        lPredicate = d => d.Id.ToString().ToLower().Contains(pFieldTemplate.ToLower());
////                        lDirBase = pList.FirstOrDefault(lPredicate);
////                        break;
////                    case "Obozn":
////                        lPredicate = d => d.Obozn.ToLower().Contains(pFieldTemplate.ToLower());
////                        lDirBase = pList.FirstOrDefault(lPredicate);
////                        break;
////                    case "Naim":
////                        lPredicate = d => d.Naim.ToLower().Contains(pFieldTemplate.ToLower());
////                        lDirBase = pList.FirstOrDefault(lPredicate);
////                        break;
////                    default:
////                        //throw (new CommonException("Нет такого поля"));
////                        break;
////                }
////
////                //lDirBase = pList.FirstOrDefault(lPredicate);
////
////                return lDirBase;
////            }
////            catch (Exception e1) { throw e1; }
////            finally { }
////        }


        //Ищет в заданном списке элемент справочника в заданном поле по заданному шаблону
        private  TDirBase FindFirstDirInList
            (string pFieldObozn, string pFieldTemplate, IEnumerable<TDirBase> pList)
        {
            try
            {
                TDirBase lDirBase = null;

                //готовим делегата условия
                Func<TDirBase, bool> lPredicate = null;

                lPredicate = d => d.GetAttrib(pFieldObozn).ToString().ToLower().Contains(pFieldTemplate.ToLower());  
                lDirBase = pList.FirstOrDefault(lPredicate);

                return lDirBase;
            }
            catch (Exception e1) { throw e1; }
            finally { }
        }



////        //Фильтруе заданный список по установленному фильтру
////        protected virtual IEnumerable<TDirBase> SelectListBySetFilter(IEnumerable<TDirBase> pList)
////        {
////            try
////            {
////                //готовим делегата условия
////                Func<TDirBase, bool> lPredicate;
////                lPredicate = null;
////
////                if (mvarListFilter.Count != 0) //Есть фильтр
////                {
////                    foreach (TFilterValue k in mvarListFilter)
////                    {
////                        switch (k.FieldObozn)
////                        {
////                            case "Id":
////                                lPredicate = d => d.Id.ToString().ToLower().Contains(k.FilterTemplate.ToLower());
////                                //pList = pList.Where(lPredicate);
////                                pList = pList.Where(lPredicate).ToList();
////                                break;
////                            case "Obozn":
////                                lPredicate = d => d.Obozn.ToLower().Contains(k.FilterTemplate.ToLower());
////                                //pList = pList.Where(lPredicate);
////                                pList = pList.Where(lPredicate).ToList();
////                                break;
////                            case "Naim":
////                                lPredicate = d => d.Naim.ToLower().Contains(k.FilterTemplate.ToLower());
////                                //pList = pList.Where(lPredicate);
////                                pList = pList.Where(lPredicate).ToList();
////                                break;
////                            default:
////                                break;
////                        }
////                        //pList = pList.Where(lPredicate);
////                    }
////                }
////                return pList;
////            }
////            catch (Exception e1) { throw e1; }
////            finally { }
////        }


        //Фильтруе заданный список по установленному фильтру
        private IEnumerable<TDirBase> SelectListBySetFilter(IEnumerable<TDirBase> pList)
        {
            try
            {
                //готовим делегата условия
                Func<TDirBase, bool> lPredicate;
                lPredicate = null;

                if (mvarListFilter.Count != 0) //Есть фильтр
                {
                    foreach (TFilterValue k in mvarListFilter)
                    {
                        lPredicate = d => d.GetAttrib(k.FieldObozn).ToString().ToLower().Contains(k.FilterTemplate.ToLower());
                        pList = pList.Where(lPredicate).ToList();
                    }
                }
                return pList;
            }
            catch (Exception e1) { throw e1; }
            finally { }
        }















































//По  заданному алиасу поля возвращает список уникальных значений из текущего списка
        public Collection<string> GetListUniqueValueForAliasField(string pAlias)
        {
            try
            {

                string pObozn;
                Collection<string> lListValue;

                pObozn = GetColumnOboznByAlias(pAlias);

                Collection<TDirBase> lCurList = GetCurList();

                var hhh = lCurList.Select(h => h.GetAttrib(pObozn).ToString())
                                  .Distinct()
                                  .OrderBy(k => k);

               lListValue = new Collection<string>();

               foreach (string lFieldValue in hhh){lListValue.Add(lFieldValue);}

               return lListValue;

            }
            catch (Exception e1) { throw e1; }
            finally { }
        }


































        public virtual string Title
        {get{return "Имя справочника не определено";}}









        #region Find...



        //Ищет элемент справочника по объекту и делает его текущим
        //при вызове справочника в контексте элемента документа
        // Поиск начианется с первой ячейки вниз списка
        //Если не находит, остается на текущей ячейке
        public virtual void FindByDir(TDirBase pDir)
        {
            try
            {
                TDirBase lDirBase;
                Collection<TDirBase> lCurList;
                ////string lFieldObozn;
                ////string lFindTemplate;
                TDirFindEventArgs lDirFindEventArgs;


                lCurList = GetCurList();


                //готовим делегата условия
                Func<TDirBase, bool> lPredicate;

                ////lPredicate = d => d == pDir;
                ////lPredicate = d => d.Obozn == pDir.Obozn;
                lPredicate = d => d.Equals(pDir);




                lDirBase = lCurList.FirstOrDefault(lPredicate);



                if (lDirBase != null)
                {
                    mvarCurItem = lDirBase;
                    lDirFindEventArgs = new TDirFindEventArgs(true, (TDirBase)GetCurItem());
                }
                else { lDirFindEventArgs = new TDirFindEventArgs(false, null); }


                FireEventFindDir(lDirFindEventArgs);

            }

            catch (Exception e1) { throw e1; }
            finally { }
        }





        //Находит ячейку с заданным критерием в текущем списке и делает ее текущей
        // Поиск начианется с текущей ячейки вниз списка
        //Если не находит, остается на текущей ячейке
        public  void FindNext(TFilterValue lFindValue)
        {
            try
            {
                TDirBase lDirBase;
                Collection<TDirBase> lCurList;
                string lFieldObozn;
                string lFindTemplate;
                TDirFindEventArgs lDirFindEventArgs;


                //lFieldObozn = lFindValue.FieldObozn;
                lFieldObozn = GetColumnOboznByAlias(lFindValue.FieldObozn);
                if (lFieldObozn == "") { throw (new CommonException("Нет такого обозначения по алиасу")); }




                lFindTemplate = lFindValue.FilterTemplate;



                if (lFindTemplate == "") { throw (new CommonException("Отсутсвует критерий поиска")); }

                lCurList = GetCurList();





////                //готовим делегата условия
////                Func<TDirBase, bool> lPredicate;
////                lPredicate = null;
////                switch (lFieldObozn)
////                {
////                    case "Id":
////                        lPredicate = d => d.Id.ToString().ToLower().Contains(lFindTemplate.ToLower());
////                        break;
////                    case "Obozn":
////                        lPredicate = d => d.Obozn.ToLower().Contains(lFindTemplate.ToLower());
////                        break;
////                    case "Naim":
////                        lPredicate = d => d.Naim.ToLower().Contains(lFindTemplate.ToLower());
////                        break;
////                    default:
////                        throw (new CommonException("Нет такого поля"));
////                }






                int lCurItemIndex;
                lCurItemIndex = GetCurItemIndex();
                if (lCurItemIndex == -1) { lDirFindEventArgs = new TDirFindEventArgs(false, null); }//вообще нет записей -> негде искать
                else
                {
                    var hhh = lCurList.Skip(lCurItemIndex + 1);// обрезаем сверху от текущей записис


                    ////lDirBase = hhh.FirstOrDefault(lPredicate);
                    lDirBase = FindFirstDirInList(lFieldObozn, lFindTemplate, hhh);  

                    if (lDirBase != null)
                    {
                        mvarCurItem = lDirBase;
                        lDirFindEventArgs = new TDirFindEventArgs(true, (TDirBase)GetCurItem());
                    }
                    else { lDirFindEventArgs = new TDirFindEventArgs(false, null); }
                }

                FireEventFindDir(lDirFindEventArgs);

            }

            catch (Exception e1) { throw e1; }
            finally { }
        }









        //Находит ячейку с заданным критерием в текущем списке и делает ее текущей
        // Поиск начианется с текущей ячейки вверх списка
        //Если не находит, остается на текущей ячейке
        public  void FindPrev(TFilterValue lFindValue)
        {
            try
            {
                TDirBase lDirBase;
                Collection<TDirBase> lCurList;
                string lFieldObozn;
                string lFindTemplate;
                TDirFindEventArgs lDirFindEventArgs;

                //lFieldObozn = lFindValue.FieldObozn;
                lFieldObozn = GetColumnOboznByAlias(lFindValue.FieldObozn);
                if (lFieldObozn == "") { throw (new CommonException("Нет такого обозначения по алиасу")); }



                lFindTemplate = lFindValue.FilterTemplate;

                if (lFindTemplate == "") { throw (new CommonException("Отсутсвует критерий поиска")); }

                lCurList = GetCurList();



////                //готовим делегата условия
////                Func<TDirBase, bool> lPredicate;
////                lPredicate = null;
////                switch (lFieldObozn)
////                {
////                    case "Id":
////                        lPredicate = d => d.Id.ToString().ToLower().Contains(lFindTemplate.ToLower());
////                        break;
////                    case "Obozn":
////                        lPredicate = d => d.Obozn.ToLower().Contains(lFindTemplate.ToLower());
////                        break;
////                    case "Naim":
////                        lPredicate = d => d.Naim.ToLower().Contains(lFindTemplate.ToLower());
////                        break;
////                    default:
////                        throw (new CommonException("Нет такого поля"));
////                }





                int lCurItemIndex;
                lCurItemIndex = GetCurItemIndex();
                if (lCurItemIndex == -1) { lDirFindEventArgs = new TDirFindEventArgs(false, null); }//вообще нет записей -> негде искать
                else
                {

                    var hhh = lCurList.Take(lCurItemIndex);// обрезаем снизу от текущей записис



                    ////lDirBase = hhh.LastOrDefault(lPredicate);
                    lDirBase = FindLastDirInList(lFieldObozn, lFindTemplate, hhh);  



                    if (lDirBase != null)
                    {
                        mvarCurItem = lDirBase;
                        lDirFindEventArgs = new TDirFindEventArgs(true, (TDirBase)GetCurItem());
                    }
                    else { lDirFindEventArgs = new TDirFindEventArgs(false, null); }

                }

                FireEventFindDir(lDirFindEventArgs);

            }

            catch (Exception e1) { throw e1; }
            finally { }
        }












        //Находит ячейку с заданным критерием в текущем списке и делает ее текущей
        // Поиск начианется с первой ячейки вниз списка
        //Если не находит, остается на текущей ячейке
        public  void Find(TFilterValue lFindValue)
        {
            try
            {
                TDirBase lDirBase;
                Collection<TDirBase> lCurList;
                string lFieldObozn;
                string lFindTemplate;
                TDirFindEventArgs lDirFindEventArgs;


        
                lFieldObozn = GetColumnOboznByAlias(lFindValue.FieldObozn);
                if (lFieldObozn == "") { throw (new CommonException("Нет такого обозначения по алиасу")); }




                lFindTemplate = lFindValue.FilterTemplate;

                if (lFindTemplate == "") { throw (new CommonException("Отсутсвует критерий поиска")); }

                lCurList = GetCurList();







//                //готовим делегата условия
//                Func<TDirBase, bool> lPredicate;
//                lPredicate = null;
//                switch (lFieldObozn)
//                {
//                    case "Id":
//                        lPredicate = d => d.Id.ToString().ToLower().Contains(lFindTemplate.ToLower());
//                        break;
//                    case "Obozn":
//                        lPredicate = d => d.Obozn.ToLower().Contains(lFindTemplate.ToLower());
//                        break;
//                    case "Naim":
//                        lPredicate = d => d.Naim.ToLower().Contains(lFindTemplate.ToLower());
//                        break;
//                    default:
//                        throw (new CommonException("Нет такого поля"));
//                }
//
//                lDirBase = lCurList.FirstOrDefault(lPredicate);


                lDirBase = FindFirstDirInList(lFieldObozn, lFindTemplate, lCurList);
 





                if (lDirBase != null)
                {
                    mvarCurItem = lDirBase;
                    lDirFindEventArgs = new TDirFindEventArgs(true, (TDirBase)GetCurItem());
                }
                else { lDirFindEventArgs = new TDirFindEventArgs(false, null); }

     
                FireEventFindDir(lDirFindEventArgs);

            }

            catch (Exception e1) { throw e1; }
            finally { }
        }








        #endregion






        //Упорядочивем  заданный список по установленной сортировке
        private  IEnumerable<TDirBase> OrderListBySetSort(IEnumerable<TDirBase> pList)
        {
            try
            {
                Func<TDirBase, object> lSelector;
                lSelector = d =>
                {
                    object k = d.GetAttrib(mvarSortValue.FieldObozn);
                    return k;
                };

                if (mvarSortValue.SortType == ESortType.OrderForward)
                {
                    pList = FullListDir.OrderBy(lSelector);
                }
                else if ((mvarSortValue.SortType == ESortType.OrderBackward))
                {
                    pList = FullListDir.OrderByDescending(lSelector);
                }
                else { throw (new CommonException("Нет типа сортировки")); }

                return pList;
            }

            catch (Exception e1) { throw e1; }
            finally { }
        }















////        public void Delete()
////        {
////            try
////            {
////                TDirBase lCurDir;
////                Collection<TDirBase> lCurListDir;
////                int lIdAfterDelete;
////
////                lCurListDir = GetCurList();
////                lCurDir = GetCurItem();
////
////                lIdAfterDelete = GetIdAfterDelete(lCurDir, lCurListDir);
////
////                if (lIdAfterDelete == -1) { throw (new CommonException("Нет текущего элемента в коллекции")); }
////
////                TDirITCompanyBase lDirITCompanyBase = (TDirITCompanyBase)lCurDir;
////                Esb.DeleteITCompany(ref lDirITCompanyBase);
////                TDirITCompanyNull lDirITCompanyNull = (TDirITCompanyNull)lDirITCompanyBase;
////                Collection<TDirITCompany> lListDir = Esb.GetListITCompany();
////
////                Collection<TDirBase> lListDirBase = new Collection<TDirBase>();
////                foreach (TDirITCompany h in lListDir){lListDirBase.Add((TDirBase)h);}
////
////                TDirBase lCurItem;
////                if (lIdAfterDelete > 0) { lCurItem = GetItemById(lIdAfterDelete, lListDirBase); }
////                else if (lIdAfterDelete == 0) { lCurItem = null; }
////                else if (lIdAfterDelete == -1) { throw (new CommonException("Нет текущего элемента в коллекции")); }
////                else { throw (new CommonException("Нет значения возврата для GetIdAfterDelete")); }
////
////                mvarFullListDir = lListDirBase;
////                mvarCurItem = lCurItem;
////
////                //дальше здесь событие что обновлено
////                FireEventUpdateList(EventArgs.Empty);
////            }
////            catch (Exception e1) { throw e1; }
////            finally { }
////        }




////        //Редактирует текущую элемент справочника, на вход объект TDirITCompanyNew  с новыми знвчениями текщей записи
////        public virtual void Edit(TDirITCompanyNew pDir)
////        {
////            try
////            {
////                TDirBase lCurDir;
////
////                //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
////                //Тут бы желательно открыть транзакцию
////
////                lCurDir = this.GetCurItem();
////                lCurDir.Obozn = pDir.Obozn;
////                lCurDir.Naim = pDir.Naim;
////
////
////                TDirITCompanyBase lDirITCompanyBase = (TDirITCompanyBase)lCurDir;
////                Esb.SaveITCompany(ref lDirITCompanyBase);
////                TDirITCompany lDirITCompany = (TDirITCompany)lDirITCompanyBase;
////                Collection<TDirITCompany> lListDir = Esb.GetListITCompany();
////
////                Collection<TDirBase> lListDirBase = new Collection<TDirBase>();
////                foreach (TDirITCompany h in lListDir)
////                {
////                    lListDirBase.Add((TDirBase)h);
////                }
////
////                TDirBase lCurItem;
////                lCurItem = GetItemById(lDirITCompany.Id, lListDirBase);
////
////                mvarFullListDir = lListDirBase;
////                mvarCurItem = lCurItem;
////
////                //дальше здесь событие что обновлено
////                FireEventUpdateList(EventArgs.Empty);
////            }
////            catch (Exception e1) { throw e1; }
////            finally { }
////        }




////        //Добавляет элемент справочника и делает его текущим
////        public virtual void Add(TDirITCompanyNew pDir)
////        {
////            try
////            {
////                TDirITCompanyBase lDirITCompanyBase = (TDirITCompanyBase)pDir;
////                Esb.SaveITCompany(ref lDirITCompanyBase);
////                TDirITCompany lDirITCompany = (TDirITCompany)lDirITCompanyBase;
////                Collection<TDirITCompany> lListDir = Esb.GetListITCompany();
////
////
////
////                Collection<TDirBase> lListDirBase = new Collection<TDirBase>();
////                foreach (TDirITCompany h in lListDir)
////                {
////                    lListDirBase.Add((TDirBase)h);
////                }
////
////
////
////
////                TDirBase lCurItem;
////                lCurItem = GetItemById(lDirITCompany.Id, lListDirBase);
////
////                mvarFullListDir = lListDirBase;
////                mvarCurItem = lCurItem;
////
////                //дальше здесь событие что обновлено
////                ////if (EventUpdateList != null) EventUpdateList(this, EventArgs.Empty);
////                FireEventUpdateList(EventArgs.Empty);
////
////            }
////
////            catch (Exception e1) { throw e1; }
////            finally { }
////        }






 

















 



 



 




        //Проверяет наличие функции у делегата
        public bool CheckEventUpdateListIsNull()
        {
            if (EventUpdateList == null) { return true; }
            else { return false; }
        }


        //Проверяет наличие функции у делегата
        public bool CheckEventFindDirIsNull()
        {
            if (EventFindDir == null) { return true; }
            else { return false; }
        }


        protected virtual void FireEventFindDir(TDirFindEventArgs pDirFindEventArgs)
        {
            try { if (EventFindDir != null) EventFindDir(this, pDirFindEventArgs); }
            catch (Exception e1) { throw e1; }
            finally { }
        }


        protected virtual void FireEventUpdateList(EventArgs pUpdateListEventArgs)
        {
            try { if (EventUpdateList != null) EventUpdateList(this, pUpdateListEventArgs); }
            catch (Exception e1) { throw e1; }
            finally { }
        }




        //Возвращает элемент коллекции по значению идентификатора
        protected TDirBase GetItemById(int pId, Collection<TDirBase> pListDir)
        {
            try
            {

                TDirBase hhh = pListDir.SingleOrDefault(r => r.Id == pId);
                return hhh;
            }

            catch (Exception e1) { throw e1; }
            finally { }
        }




        public virtual void SetCurItem(int pId)
        {
            try
            {
                Collection<TDirBase> lCurList;
                TDirBase lCurItem;

                lCurList = GetCurList();
                lCurItem = lCurList.Single(p => p.Id == pId);
                mvarCurItem = lCurItem;
            }
            catch (Exception e) { throw e; }
            finally { }
        }


        //Возвращает ИД следующего после удаления текущего элемента
        protected int GetIdAfterDelete(TDirBase pDir, Collection<TDirBase> pListDir)
        {
            try
            {
                int lIndex;
                int Result;
                TDirBase lAfterDeleteDir;

                lIndex = pListDir.IndexOf(pDir);

                if (lIndex == -1) { Result = -1; }//нет исходного объекта в коллекции
                else
                {
                    lAfterDeleteDir = pListDir.ElementAtOrDefault(lIndex + 1);
                    if (lAfterDeleteDir == null)
                    {
                        lAfterDeleteDir = pListDir.ElementAtOrDefault(lIndex - 1);
                        if (lAfterDeleteDir == null) { Result = 0; }//Нет объектов после удаления}
                        else { Result = lAfterDeleteDir.Id; }//Возвращаем предыдйущий объект}
                    }
                    else { Result = lAfterDeleteDir.Id; }//возвращаем следующий объект

                }
                return Result;
            }

            catch (Exception e1) { throw e1; }
            finally { }
        }






        //Возвращает индекс текущего итема в текущей последовательности
        //если нет текущего итема возвращает -1
        // 0 это превыйэлемент последоватедьности (для справки)
        protected int GetCurItemIndex()
        {
            try
            {
                int lIndex;
                int lResult;
                Collection<TDirBase> lCurList;
                TDirBase lCurItem;

                lCurItem = GetCurItem();

                if (lCurItem == null) { lResult = -1; }
                else
                {
                    lCurList = GetCurList();
                    lIndex = lCurList.IndexOf(lCurItem);
                    if (lIndex == -1) { throw (new CommonException("Текущий элемент не найден")); }
                    else { lResult = lIndex; }
                }

                return lResult;
            }

            catch (Exception e1) { throw e1; }
            finally { }
        }



        //Возвращает текущий элемент
        public TDirBase GetCurItem()
        { return mvarCurItem; }



 





        //Возвращает первый элемент
        protected TDirBase GetFirstItem(Collection<TDirBase> pListDir)
        {
            try
            {

                TDirBase lDirBase;

                ////lDirITCompany = pListDir.First();
                lDirBase = pListDir.FirstOrDefault();

                return lDirBase;

            }

            catch (Exception e1) { throw e1; }
            finally { }
        }


        //Возвращает представление для клиента
        public virtual object GetCurListView()
        {
            try
            {
                Collection<TDirBase> lCurrentList = GetCurList();


                var hhh = lCurrentList.Select(p => new
                {
                    Id = p.Id,
                    Обозначение = p.Obozn,
                    Наименование = p.Naim,
                }).ToList();

                return hhh;

            }
            catch (Exception e1) { throw e1; }
            finally { }
        }









        protected Collection<TDirBase> FullListDir
        {
            get{return mvarFullListDir;}
        }




















































































        protected TEsb Esb
        {
            get
            {
                try { return TEsb.GetEsb(); }
                catch (Exception e) { throw e; }
                finally { }
            }
        }


        protected string GetColumnOboznByAlias(string pAlias)
        {
            try
            {
                TAliasForField lOboznAndAlias;
                string lObozn;

                Collection<TAliasForField> lListOboznAndAlias = GetListOboznAndAlias();

                lOboznAndAlias = lListOboznAndAlias.FirstOrDefault(d => d.Alias == pAlias);
                if (lOboznAndAlias != null) { lObozn = lOboznAndAlias.Obozn; }
                else { lObozn = ""; }

                return lObozn;

            }

            catch (Exception e1) { throw e1; }
            finally { }
        }

        protected virtual Collection<TAliasForField> GetListOboznAndAlias()
        {

            Collection<TAliasForField> lList;

            lList = new Collection<TAliasForField>();
            lList.Add(new TAliasForField("Id", "Id"));
            lList.Add(new TAliasForField("Obozn", "Обозначение"));
            lList.Add(new TAliasForField("Naim", "Наименование"));

            return lList;
        }

        protected string GetColumnAliasByObozn(string pObozn)
        {
            try
            {
                TAliasForField lOboznAndAlias;
                string lAlias;

                Collection<TAliasForField> lListOboznAndAlias = GetListOboznAndAlias();

                lOboznAndAlias = lListOboznAndAlias.FirstOrDefault(d => d.Obozn == pObozn);
                if (lOboznAndAlias != null) { lAlias = lOboznAndAlias.Alias; }
                else { lAlias = ""; }

                return lAlias;

            }

            catch (Exception e1) { throw e1; }
            finally { }
        }





        




   



  


 



  


 



  










        public virtual TDirBase FindById(int pId)
        { throw (new CommonException("Функция не реализована")); }

        public virtual TDirBase FindByObozn(string pObozn)
       {throw (new CommonException("Функция не реализована"));}

        public virtual TDirBase FindByNaim (string pNaim)
        {throw (new CommonException("Функция не реализована"));}




        









 



    }
}
